package cn.harmonyoslearn.navrouter.utils;

import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.RefreshQueue;
import org.jetbrains.annotations.NotNull;

import java.io.*;
import java.net.JarURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Enumeration;
import java.util.Objects;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * 文件处理模块
 */
public class FileUtil {
    /**
     * 将内容写入到文件中
     *
     * @param filePath 文件路径
     * @param fileName 文件名称
     * @param content  需要写入的文本内容
     * @param isFormatJson 是否需要格式化json
     */
    public static void write(String filePath, String fileName, String content, Boolean isFormatJson) {
        write(filePath + "/" + fileName, content, isFormatJson);
    }

    /**
     * 将内容写入到文件中
     *
     * @param uri 文件路径
     * @param content  需要写入的文本内容
     * @param isFormatJson 是否需要格式化json
     */
    public static void write(String uri, String content, Boolean isFormatJson) {
        File file = new File(uri);
        File parentDir = file.getParentFile(); // 获取父目录

        try {
            // 如果父目录不存在，则创建父目录
            if (!parentDir.exists()) {
                if (parentDir.mkdirs()) { // 创建所有不存在的父目录
                    System.out.println("目录创建成功: " + parentDir.getAbsolutePath());
                } else {
                    System.out.println("目录创建失败: " + parentDir.getAbsolutePath());
                }
            }

            // 如果文件不存在则创建文件
            if (file.createNewFile()) {
                System.out.println("文件创建成功: " + file.getAbsolutePath());
            } else {
                System.out.println("文件已存在: " + file.getAbsolutePath());
            }

            FileWriter writer = new FileWriter(file);
            if (isFormatJson) {
                writer.write(JsonUtil.formatJson(content));
            } else {
                writer.write(content);
            }
            writer.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 判断文件是否存在
     */
    public static boolean isFile(String filePath) {
        VirtualFile file = LocalFileSystem.getInstance().findFileByPath(filePath);
        // 检查文件是否存在
        return file != null && file.exists();
    }

    /**
     * 读取文件内容的方法
     *
     * @param filePath 文件路径
     * @return 文件内容
     */
    public static String readFileContent(String filePath) {
        StringBuilder contentBuilder = new StringBuilder();
        try {
            // 使用Files.readAllLines读取所有行
            Files.readAllLines(Paths.get(filePath), StandardCharsets.UTF_8).forEach(line -> {
                contentBuilder.append(line).append(System.lineSeparator());
            });
        } catch (IOException e) {
            return null;
        }
        return contentBuilder.toString();
    }

    /**
     * 读取Resources目录下的文件内容
     *
     * @param resourcePath 路径
     * @return 文件文本内容
     */
    public static String readResourceFileContent(String resourcePath) {
        StringBuilder contentBuilder = new StringBuilder();
        try (
                InputStream inputStream = FileUtil.class.getClassLoader().getResourceAsStream(resourcePath);
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))
        ) {
            String line;
            while ((line = reader.readLine()) != null) {
                contentBuilder.append(line).append(System.lineSeparator());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return contentBuilder.toString();
    }

    /**
     * 获取项目根目录
     */
    public static String getBasePath(@NotNull AnActionEvent e) {
        Project project = e.getProject();
        String path = "";
        if (project != null) {
            path = project.getBasePath();
        } else {
            return null;
        }
        return path;
    }


    /**
     * 将带名称的路径转化成不带名称的路径
     * @param filePathAndName 带文件名称的路径
     * @return 不带文件名称的路径
     */
    public static String getNotNameFilePath(String filePathAndName) {
        String filePath = filePathAndName;

        if (filePathAndName.contains(".")) {
            String[] paths = filePathAndName.split("/");
            // 去除最后一项
            if (paths.length > 1) {
                String[] directories = new String[paths.length - 1];
                System.arraycopy(paths, 0, directories, 0, paths.length - 1);
                filePath = String.join("/", directories);
                System.out.println("处理后的路径: " + filePath);
            } else {
                System.out.println("无法去除最后一项，因为路径不包含 '/'");
            }
        }
        return filePath;
    }

    /**
     * 在编辑器中打开文件视图
     *
     * @param filePath 文件路径，需要带名称
     */
    public static void openFile(Project project, String filePath) {
        // 确保文件系统已经加载
        ApplicationManager.getApplication().invokeLater(() -> {
            // 获取文件的虚拟文件对象
            VirtualFile file = LocalFileSystem.getInstance().findFileByPath(filePath);
            if (file != null) {
                // 打开文件
                FileEditorManager.getInstance(project).openFile(file, true);
            } else {
                // 文件未找到，可以在这里处理错误
                System.out.println("File not found: " + filePath);
            }
        });
    }

    /**
     * 刷新文件
     * @param filePath 文件路径需要带名称
     */
    public static void refreshAndFindFileByPath(String filePath) {
        try {
            VirtualFile virtualFile1 = LocalFileSystem.getInstance().refreshAndFindFileByPath(filePath);
            if (virtualFile1 != null) {
                RefreshQueue.getInstance().refresh(false, true, null, virtualFile1);
            }
        } catch (Exception e){
            System.out.println("refreshAndFindFileByPath Error " + e.getMessage());
        }
    }

    /**
     * 复制资源目录到项目目录
     *
     * @param resourcePath 资源路径
     * @param targetPath   目标路径
     */
    public static void copyResourceFolderToProject(String resourcePath, String targetPath) throws IOException {
        // 获取资源文件夹的 URL
        URL resourceDirUrl = FileUtil.class.getClassLoader().getResource(resourcePath);
        if (resourceDirUrl == null) {
            throw new IllegalArgumentException("Resource directory not found: " + resourcePath);
        }

        // 获取项目目标文件夹的路径
        Path targetDir = Paths.get(targetPath);
        if (!Files.exists(targetDir)) {
            Files.createDirectories(targetDir);
        }

        // 递归复制资源文件夹到项目目录
        copyDirectory(resourceDirUrl, resourcePath, targetDir);
    }

    /**
     * 递归复制资源文件夹到项目目录
     *
     * @param resourceDirUrl 资源路径的 URL
     * @param targetDir      目标路径
     */
    private static void copyDirectory(URL resourceDirUrl, String resourcePath, Path targetDir) throws IOException {
        try {
            JarURLConnection jarConnection = (JarURLConnection) resourceDirUrl.openConnection();
            JarFile jarFile = jarConnection.getJarFile();

            Enumeration<JarEntry> entries = jarFile.entries();
            while (entries.hasMoreElements()) {
                JarEntry entry = entries.nextElement();
                String entryName = entry.getName();

                // 只处理指定资源路径下的条目
                if (entryName.startsWith(resourcePath) && !entry.isDirectory()) {
                    // 计算 entryName 相对于 resourcePath 的路径
                    String relativePath = entryName.substring(resourcePath.length());
                    if (relativePath.startsWith("/")) {
                        relativePath = relativePath.substring(1);
                    }
                    Path targetFilePath = targetDir.resolve(relativePath);

                    // 确保目标目录存在
                    Files.createDirectories(targetFilePath.getParent());

                    // 复制条目到目标路径
                    try (InputStream inputStream = jarFile.getInputStream(entry)) {
                        Files.copy(inputStream, targetFilePath, StandardCopyOption.REPLACE_EXISTING);
                    } catch (IOException e) {
                        System.out.println("copyResourceFolderToProject Files.copy Error " + e.getMessage());
                    }
                }
            }
        } catch (Exception e) {
            System.out.println("copyResourceFolderToProject Error " + e.getMessage());
        }
    }


}
